package com.wn.consumer.confirm;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author yellow Docter
 * @date 2022 -09-01
 * @desc
 *
 *  channel 连接通道
 *
 *           消费者手动确认消息消费; 参数1：消息id；参数2：是否批量确认
 *           channel.basicAck(); 进行消息确认
 *
 *           // 重新投递的消息: 直接拒绝掉
 *           // 消息投递序号 是否将消息回退到队列
 *           channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
 *
 *           // 该消息没有被重新投递过, 进行重投
 *           // 消息投递序号  是否批量  是否将消息回退到队列
 *           channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
 *
 *  Message  msg对象
 *     message.getMessageProperties()  获取消息的属性
 *
 */
@Component
@Slf4j
public class ConfirmConsumer {

    @RabbitListener(
            bindings = {
                    @QueueBinding(
                            value = @Queue(name="confirm-queue"),//队列
                            exchange = @Exchange(
                                    name = "exchange-confirm",
                                    type = ExchangeTypes.DIRECT
                            ),
                            key = "confirm"
                    )
            }
    )
    public void consumer(String msg, Channel channel, Message message) throws IOException {

        try {
            int i = 10/0;
            //消息消费 进行手动确认
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            log.info("消费了消息:{}",msg);

        } catch (Exception e) {

            e.printStackTrace();

//            // 分析：消息消费失败了，希望把消息重投到队列中，再次进行消费，如果还是消费失败就拒绝消息
//            // 获取消息是否是重投的标记
            Boolean redelivered = message.getMessageProperties().getRedelivered();
            if (redelivered) {
                // 重新投递的消息: 直接拒绝掉
                // 消息投递序号 是否将消息回退到队列

                //channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
                //System.out.println("消息消费异常，消息作废...");
                //存储到数据库中 进行 指定时间统一处理

            } else {
                // 该消息没有被重新投递过, 进行重投
                // 消息投递序号  是否批量  是否将消息回退到队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
                System.out.println("消息消费异常，消息进行重投");
            }

        }


    }

}
